"""
CSV文件加载器
提供CSV文件的读取和解析功能
"""

import csv
import os
from typing import List, Tuple, Optional
from PySide6.QtWidgets import QMessageBox


class CSVLoader:
    """CSV文件加载器"""
    
    @staticmethod
    def load_csv_file(file_path: str, encoding: str = 'utf-8', delimiter: str = ',', use_first_row_as_header: bool = True) -> Tuple[List[List[str]], List[str], Optional[str]]:
        """
        加载CSV文件
        
        Args:
            file_path: CSV文件路径
            encoding: 文件编码
            delimiter: 分隔符
            use_first_row_as_header: 是否使用第一行作为表头
            
        Returns:
            Tuple[List[List[str]], List[str], Optional[str]]: (数据, 表头, 错误信息)
        """
        try:
            if not os.path.exists(file_path):
                return [], [], f"文件不存在: {file_path}"
                
            data = []
            headers = []
            
            # 尝试不同的编码
            encodings_to_try = [encoding, 'utf-8', 'gbk', 'gb2312', 'utf-8-sig']
            
            for enc in encodings_to_try:
                try:
                    with open(file_path, 'r', encoding=enc, newline='') as file:
                        # 先尝试自动检测分隔符
                        sample = file.read(1024)
                        file.seek(0)
                        
                        # 检测分隔符
                        detected_delimiter = CSVLoader._detect_delimiter(sample)
                        if detected_delimiter:
                            delimiter = detected_delimiter
                        
                        # 读取CSV数据
                        csv_reader = csv.reader(file, delimiter=delimiter)
                        
                        # 读取所有行
                        all_rows = list(csv_reader)
                        
                        if all_rows:
                            if use_first_row_as_header:
                                # 使用第一行作为表头
                                headers = [str(cell).strip() for cell in all_rows[0]]
                                # 其余行作为数据
                                for row in all_rows[1:]:
                                    # 确保每行的列数一致
                                    while len(row) < len(headers):
                                        row.append("")
                                    data.append([str(cell).strip() for cell in row])
                            else:
                                # 不使用第一行作为表头，所有行都是数据
                                max_cols = max(len(row) for row in all_rows) if all_rows else 0
                                for row in all_rows:
                                    # 确保每行的列数一致
                                    while len(row) < max_cols:
                                        row.append("")
                                    data.append([str(cell).strip() for cell in row])
                                
                        break
                        
                except UnicodeDecodeError:
                    continue
                except Exception as e:
                    return [], [], f"读取文件时出错: {str(e)}"
            else:
                return [], [], f"无法使用任何编码读取文件: {file_path}"
                
            return data, headers, None
            
        except Exception as e:
            return [], [], f"加载CSV文件失败: {str(e)}"
    
    @staticmethod
    def _detect_delimiter(sample: str) -> Optional[str]:
        """自动检测分隔符"""
        delimiters = [',', ';', '\t', '|']
        max_count = 0
        best_delimiter = None
        
        for delimiter in delimiters:
            count = sample.count(delimiter)
            if count > max_count:
                max_count = count
                best_delimiter = delimiter
                
        return best_delimiter
    
    @staticmethod
    def save_csv_file(file_path: str, data: List[List[str]], headers: List[str], 
                     encoding: str = 'utf-8', delimiter: str = ',') -> Optional[str]:
        """
        保存数据到CSV文件
        
        Args:
            file_path: 保存路径
            data: 数据
            headers: 表头
            encoding: 编码
            delimiter: 分隔符
            
        Returns:
            Optional[str]: 错误信息，成功时返回None
        """
        try:
            with open(file_path, 'w', encoding=encoding, newline='') as file:
                csv_writer = csv.writer(file, delimiter=delimiter)
                
                # 写入表头
                csv_writer.writerow(headers)
                
                # 写入数据
                for row in data:
                    # 确保每行的列数一致
                    while len(row) < len(headers):
                        row.append("")
                    csv_writer.writerow(row)
                    
            return None
            
        except Exception as e:
            return f"保存CSV文件失败: {str(e)}"
    
    @staticmethod
    def get_file_info(file_path: str) -> Tuple[int, int, Optional[str]]:
        """
        获取CSV文件信息
        
        Args:
            file_path: 文件路径
            
        Returns:
            Tuple[int, int, Optional[str]]: (行数, 列数, 错误信息)
        """
        try:
            data, headers, error = CSVLoader.load_csv_file(file_path)
            if error:
                return 0, 0, error
                
            row_count = len(data)
            col_count = len(headers) if headers else 0
            
            return row_count, col_count, None
            
        except Exception as e:
            return 0, 0, f"获取文件信息失败: {str(e)}"


class CSVImportDialog:
    """CSV导入对话框"""
    
    @staticmethod
    def show_import_options(parent, file_path: str) -> Tuple[bool, dict]:
        """
        显示CSV导入选项对话框
        
        Args:
            parent: 父窗口
            file_path: 文件路径
            
        Returns:
            Tuple[bool, dict]: (是否确认, 导入选项)
        """
        from PySide6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, 
                                      QComboBox, QCheckBox, QDialogButtonBox, QFormLayout,
                                      QSpinBox, QGroupBox)
        
        dialog = QDialog(parent)
        dialog.setWindowTitle("CSV导入选项")
        dialog.setModal(True)
        dialog.resize(400, 300)
        
        layout = QVBoxLayout(dialog)
        
        # 文件信息
        info_group = QGroupBox("文件信息")
        info_layout = QFormLayout(info_group)
        
        file_info_label = QLabel(os.path.basename(file_path))
        info_layout.addRow("文件名:", file_info_label)
        
        # 获取文件信息
        row_count, col_count, error = CSVLoader.get_file_info(file_path)
        if error:
            row_count_label = QLabel("无法读取")
            col_count_label = QLabel("无法读取")
        else:
            row_count_label = QLabel(f"{row_count:,}")
            col_count_label = QLabel(f"{col_count}")
            
        info_layout.addRow("行数:", row_count_label)
        info_layout.addRow("列数:", col_count_label)
        
        layout.addWidget(info_group)
        
        # 导入选项
        options_group = QGroupBox("导入选项")
        options_layout = QFormLayout(options_group)
        
        # 编码选择
        encoding_combo = QComboBox()
        encoding_combo.addItems(['utf-8', 'gbk', 'gb2312', 'utf-8-sig'])
        encoding_combo.setCurrentText('utf-8')
        options_layout.addRow("编码:", encoding_combo)
        
        # 分隔符选择
        delimiter_combo = QComboBox()
        delimiter_combo.addItems([',', ';', '\t', '|'])
        delimiter_combo.setCurrentText(',')
        options_layout.addRow("分隔符:", delimiter_combo)
        
        # 第一行作为表头
        header_checkbox = QCheckBox("第一行作为表头")
        header_checkbox.setChecked(True)
        options_layout.addRow("", header_checkbox)
        
        # 跳过空行
        skip_empty_checkbox = QCheckBox("跳过空行")
        skip_empty_checkbox.setChecked(True)
        options_layout.addRow("", skip_empty_checkbox)
        
        layout.addWidget(options_group)
        
        # 按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)
        
        # 执行对话框
        if dialog.exec() == QDialog.Accepted:
            options = {
                'encoding': encoding_combo.currentText(),
                'delimiter': delimiter_combo.currentText(),
                'use_first_row_as_header': header_checkbox.isChecked(),
                'skip_empty_rows': skip_empty_checkbox.isChecked()
            }
            return True, options
        else:
            return False, {} 